﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Kwan.Data.Mappings
{
    [AttributeUsage(AttributeTargets.Property| AttributeTargets.Class|AttributeTargets.Enum|  AttributeTargets.Struct)]
    public abstract class PropertyCastAttribute:Attribute
    {
        public abstract object ToProperty(object value,Type ptype,object source);

        public abstract object ToColumn(object value, Type ptype, object source);
        internal static object CastValue(string table, string column, object value)
        {
            //PropertyMapper pm;

            ObjectMapper om = ObjectMapper.GetOM(table);
           
            //    if (om == null)
            //        return value;
            //    pm = om[column];
            //    if (pm != null && pm.Cast != null)
            //        return pm.Cast.ToColumn(value, pm.Handler.Property.PropertyType, null);
            
           
            //return value;
            return CastValue(om, column, value);
        }
        internal static object CastValue(ObjectMapper om, string column, object value)
        {

            PropertyMapper pm;
            if (om == null)
                return value;
            pm = om[column];
            if (pm != null && pm.Cast != null)
                return pm.Cast.ToColumn(value, pm.Handler.Property.PropertyType, null);


            return value;
        }
    }
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Struct)]
    public class EnumToString : PropertyCastAttribute
    {
        public override object ToProperty(object value, Type ptype,object source)
        {
            return Enum.Parse(ptype, value.ToString());
        }
        public override object ToColumn(object value, Type ptype, object source)
        {
            return value.ToString();
        }
    }
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Struct)]
    public class EnumToInt : PropertyCastAttribute
    {
        public override object ToColumn(object value, Type ptype, object source)
        {
            return value.GetHashCode();
        }
        public override object ToProperty(object value, Type ptype, object source)
        {
            int result = Convert.ToInt32(value);
            Array values = Enum.GetValues(ptype);
            for (int i = 0; i < values.Length; i++)
            {
                if (values.GetValue(i).GetHashCode() == result)
                {
                    return values.GetValue(i);
                }
            }
            return values.GetValue(0);
            
        }
    }
    [AttributeUsage(AttributeTargets.Property)]
    public class RelationToOne : PropertyCastAttribute
    {
        public RelationToOne(string column)
        {
            Column = column;
        }
        public string Column
        {
            get;
            set;
        }
        public override object ToColumn(object value, Type ptype,object source)
        {
            ObjectMapper om = ObjectMapper.GetOM(ptype);
            PropertyMapper pm = om[Column];
            return pm.Handler.Get(value);
        }
        public override object ToProperty(object value, Type ptype,object source)
        {
            ObjectMapper om = ObjectMapper.GetOM(ptype);
            ObjectMapper otherom = ObjectMapper.GetOM(source.GetType());
            PropertyMapper otherpm = otherom[Column];

            return null;
        }

    }
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Struct)]
    public class StringCrypto:PropertyCastAttribute
    {
        private BlowfishNET.JavaInterop.BlowfishEasy mBlowfish;
        public StringCrypto()
        {
            mBlowfish = new BlowfishNET.JavaInterop.BlowfishEasy("3djfh023jfkcfjgDF");
        }
        public StringCrypto(string key)
        {
            mBlowfish = new BlowfishNET.JavaInterop.BlowfishEasy(key);
        }

        public override object ToProperty(object value, Type ptype, object source)
        {

            return DecryptString((string)value);
        }

        public override object ToColumn(object value, Type ptype, object source)
        {

            return EncryptString((string)value);
        }
        public  string EncryptString(string value)
        {
            if (string.IsNullOrEmpty(value))
                return value;
            return mBlowfish.EncryptString(value);
        }
        public  string DecryptString(string value)
        {
            if (string.IsNullOrEmpty(value))
                return value;
            return mBlowfish.DecryptString(value);
        }
    }
    
}
